package org.metasketch.editor.toolbox;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.metasketch.diagram.javafx.graphics.BaseGraphic;
import org.metasketch.diagram.javafx.graphics.BaseLink;
import org.metasketch.model.CommonIdentified;

public class PopupMenuRegistry {

	Map<String, List<PopupMenuEntry>> graphicalTypeMenus = new HashMap<String, List<PopupMenuEntry>>();

	Map<Class, List<PopupMenuEntry>> semanticalTypeMenus = new HashMap<Class, List<PopupMenuEntry>>();

	Map<Class, List<PopupMenuEntry>> inheritedSemanticalTypeMenus = new HashMap<Class, List<PopupMenuEntry>>();

	public void addGraphicalMenuEntry(String type, PopupMenuEntry entry) {
		List<PopupMenuEntry> list = graphicalTypeMenus.get(type);
		if (list == null) {
			list = new ArrayList<PopupMenuEntry>();
			graphicalTypeMenus.put(type, list);
		}

		list.add(entry);
	}

	public void addGraphicalMenuEntry(String type, String name, String script) {
		addGraphicalMenuEntry(type, new PopupMenuEntry(name, script));
	}

	public void addSemanticalMenuEntry(Class type, PopupMenuEntry entry) {
		List<PopupMenuEntry> list = semanticalTypeMenus.get(type);
		if (list == null) {
			list = new ArrayList<PopupMenuEntry>();
			semanticalTypeMenus.put(type, list);
		}

		list.add(entry);
	}

	public void addSemanticalMenuEntry(Class type, String name, String script) {
		addSemanticalMenuEntry(type, new PopupMenuEntry(name, script));
	}

	public void addInheritedSemanticalMenuEntry(Class type,
			PopupMenuEntry entry) {
		List<PopupMenuEntry> list = inheritedSemanticalTypeMenus.get(type);
		if (list == null) {
			list = new ArrayList<PopupMenuEntry>();
			inheritedSemanticalTypeMenus.put(type, list);
		}

		list.add(entry);
	}

	public void addInheritedSemanticalMenuEntry(Class type, String name,
			String script) {
		addInheritedSemanticalMenuEntry(type, new PopupMenuEntry(name,
				script));
	}

	public List<PopupMenuEntry> getEntries(BaseGraphic source) {

		Object semantic = null;

		semantic = source.getSemantic();

		Class type = null;
		if (semantic != null)
			type = semantic.getClass();

		return getEntries(source.getGraphicNode().getType(), type);
	}

	public List<PopupMenuEntry> getEntries(BaseLink source) {

		Object semantic = null;

		semantic = source.getSemantic();

		Class type = null;
		if (semantic != null)
			type = semantic.getClass();

		return getEntries(source.getGraphicNode().getType(), type);
	}

	public List<PopupMenuEntry> getEntries(String graphicType, Class type) {
		List<PopupMenuEntry> list = new ArrayList<PopupMenuEntry>();

		// String graphicType = source.getGraphicNode().getType();

		List<PopupMenuEntry> entries = graphicalTypeMenus.get(graphicType);
		if (entries != null)
			list.addAll(entries);

		if (type == null)
			return list;

		// Class type = source.getSemantic().getClass();

		List<PopupMenuEntry> semanticEntries = semanticalTypeMenus
				.get(type);
		if (semanticEntries != null)
			list.addAll(semanticEntries);

		Set<Class> types = inheritedSemanticalTypeMenus.keySet();
		for (Class candidate : types) {
			if (candidate.isAssignableFrom(type)) {
				List<PopupMenuEntry> inheritedEntries = inheritedSemanticalTypeMenus
						.get(candidate);
				if (inheritedEntries != null)
					list.addAll(inheritedEntries);
			}
		}

		return list;

	}

}
